/* Copyright (C) 1997-2005, Antony L Hosking.
 * All rights reserved.  */
package Symbol;
import java.util.HashMap;

class Binder<K,V> {
    V value;
    K prevtop;
    Binder<K,V> tail;
    Binder(V v, K p, Binder<K,V> t) {
	value = v;
	prevtop = p;
	tail = t;
    }
}

/**
 * The Table class is similar to java.util.HashMap, except that
 * there is a scope mechanism.
 */
public class Table<K,V> {
    private HashMap<K, Binder<K,V>> map = new HashMap<K, Binder<K,V>>();
    private K top;
    private Binder<K,V> marks;

    public V get(K key) {
	Binder<K,V> e = map.get(key);
	if (e == null) return null;
	else return e.value;
    }

    public V put(K key, V value) {
	Binder<K,V> e = map.put(key, new Binder<K,V>(value, top, map.get(key)));
	top = key;
	if (e == null) return null;
	else return e.value;
    }

    /**
     * Remembers the current state of the Table.
     */
    public void beginScope() {
	marks = new Binder<K,V>(null,top,marks); top=null;
    }

    /** 
     * Restores the table to what it was at the most recent beginScope that
     * has not already been ended.
     */
    public void endScope() {
	while (top!=null) {
	    Binder<K,V> e = map.get(top);
	    if (e.tail!=null) map.put(top,e.tail);
	    else map.remove(top);
	    top = e.prevtop;
	}
	top=marks.prevtop;
	marks=marks.tail;
    }

    public java.util.Set<K> keySet() {
	return map.keySet();
    }
}
